

#include "skeletalActor.h"
#include "renderer.h"
#include "input.h"
#include "boneActor.h"
SkeletalActor::SkeletalActor(){

drawType=DRAW_SKELETAL;
sceneShaderID="skeletal";
bUseShader=true;

registerProperties();

}

SkeletalActor::~SkeletalActor(){}

void SkeletalActor::registerProperties(){

createMemberID("BONES",&bones,this);
Actor::registerProperties();
}



void SkeletalActor::setup(){

    Actor::setup();

    boneTransforms=new Matrix4f[renderer->vboList[vboMeshID]->boneCount];
    invBoneTransforms=new Matrix4f[renderer->vboList[vboMeshID]->boneCount];


    for (int i=0; i< renderer->vboList[vboMeshID]->boneCount; i++){

        boneTransforms[i].identity();
        invBoneTransforms[i]=*renderer->vboList[vboMeshID]->bones[i]->invBoneMatrix;
        if ((int)bones.size()==i){
            bones.push_back(new BoneActor);
            bones[i]->name=renderer->vboList[vboMeshID]->bones[i]->name;
            renderer->actorList.push_back(bones[i]);
            bones[i]->bUseTransformMatrix=true;
            bones[i]->bRemoveable=false;
            bones[i]->drawType=DRAW_CUBE;
            bones[i]->scale=bones[i]->scale*0.25;
            bones[i]->base=this;
            }
        bones[i]->originalMatrix=*renderer->vboList[vboMeshID]->bones[i]->boneMatrix;

        cout << "created new bone: " << bones[i]->name << endl;

        }

//connect parents...
    for (int i=0; i< renderer->vboList[vboMeshID]->boneCount; i++){
        for (int j=0;j<renderer->vboList[vboMeshID]->boneCount;j++){
            if (renderer->vboList[vboMeshID]->bones[i]->parentBone)
                if (renderer->vboList[vboMeshID]->bones[j]==renderer->vboList[vboMeshID]->bones[i]->parentBone){
                cout << "connecting " << bones[i]->name << "  with " << bones[j]->name <<endl;
                bones[i]->base=bones[j];
                j=100;
                }
            else{
              bones[i]->base=this;
              bones[i]->baseMatrix=bones[i]->originalMatrix*renderer->inverseCameraMatrix;
              }
            }
    }
}


void SkeletalActor::drawSkeletal(){


    if (renderer->vboList[vboMeshID]){
        renderer->drawColladaMesh(renderer->vboList[vboMeshID]);

        if (renderer->vboList[vboMeshID]->vertexInterpretation==GL_POINTS){
            renderer->setupShading("color");
            glutSolidCube(1/scale.x);
            }
    }
}

void SkeletalActor::drawCollision(){

    //we actually need to use the shader here, or we get weird anomalities when picking...
    renderer->setupShading(sceneShaderID);
    updateShaders();

    Actor::drawCollision();
}

void SkeletalActor::trigger(Actor * other){

    cout << "yay!" << endl;
}

void SkeletalActor::update(double deltaTime){

    Actor::update(deltaTime);

    for (uint i=0;i<bones.size();i++){
        boneTransforms[i]=  bones[i]->baseMatrix * *renderer->vboList[vboMeshID]->bones[i]->invBoneMatrix * *renderer->vboList[vboMeshID]->bindShapeMatrix;
    }
}

void SkeletalActor::updateShaders(){

       GLint uniform_location=0;

        if (renderer->vboList[vboMeshID]){
            uniform_location = glGetUniformLocationARB(renderer->shaderList[sceneShaderID]->shader, "boneTransforms");
            glUniformMatrix4fv(uniform_location,renderer->vboList[vboMeshID]->boneCount,false,(GLfloat*)boneTransforms[0]);
            }

      Actor::updateShaders();
}

void SkeletalActor::remove(){

    for (int i=(int)bones.size()-1;i>=0;i--){
        bones[i]->remove();
        }

    bones.clear();

    Actor::remove();
}

void SkeletalActor::create(){renderer->addActor(this);}
